home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- *
- * NSSDC/CDF CDFstats (statistics).
- *
- * Version 2.0, 4-Mar-92, ST Systems (STX)
- *
- * Modification history:
- *
- * V1.0 10-Apr-91, J Love Original version.
- * V1.1 25-Jun-91, J Love CDF_EPOCH added as a data type. Added QOP.
- * Added PageInst.
- * V1.2 1-Aug-91, J Love TRUE/FALSE. Added range checking. Added
- * EPOCH display. Use 'Exit'/'ExitBAD'. Use
- * 'CDFlib'. Added min/max checking within the
- * valid range. Added output option.
- * V2.0 4-Mar-92, J Love Fixed online instructions. Broke into smaller
- * pieces for IBM-PC port. Changes for IBM-RS6000
- * port. Added option to filter out fill values.
- *
- ******************************************************************************/
-
- #include "cdfdist.h"
-
- #define CDFSTATS /* Define this in only one source file for CDFstats
- and it must be before 'cdfstats.h' is included. */
- #include "cdfstats.h"
-
- /******************************************************************************
- * Online help.
- ******************************************************************************/
-
- static char *instructions[] = {
- #if defined(vms)
- "Usage: $ CDFSTATS [/[NO]RANGE] [/[NO]FILL] [/OUTPUT=<file-path>]",
- " <cdf-path>",
- #endif
- #if defined(unix)
- "Usage: % cdfstats [-[no]range] [-[no]fill] [-output <file-path>]",
- " <cdf-path>",
- #endif
- #if defined(__MSDOS__)
- "Usage: > cdfstats [-[no]range] [-[no]fill] [-output <file-path>]",
- " <cdf-path>",
- #endif
- "",
- "Purpose: CDFstats displays statistics about the variables in a CDF.",
- " These include the minimum and maximum values and whether",
- " or not the variable is monotonic.",
- "",
- "Parameter(s): <cdf-path>",
- " The pathname of the CDF to check (do not enter an",
- " extension).",
- "",
- #if defined(vms)
- "Qualifier(s): /[NO]RANGE",
- #endif
- #if defined(unix) | defined(__MSDOS__)
- "Qualifier(s): -[no]range",
- #endif
- " Specifies whether or not range checking will be performed",
- " (using the VALIDMIN/VALIDMAX attributes if they exist).",
- #if NSSDC_STANDARD
- " The default is range checking on.",
- #else
- " The default is range checking off.",
- #endif
- "",
- #if defined(vms)
- "Qualifier(s): /[NO]FILL",
- #endif
- #if defined(unix) | defined(__MSDOS__)
- "Qualifier(s): -[no]fill",
- #endif
- " Specifies whether or not fill values will be filtered",
- " out when collecting statistics (using the FILLVAL",
- " attribute if it exists). Fill values are filtered out",
- " by default.",
- #if NSSDC_STANDARD
- " attribute if it exists). Fill values are filtered out",
- " by default.",
- #else
- " attribute if it exists). Fill values are not filtered",
- " out by default.",
- #endif
- "",
- #if defined(vms)
- " /OUTPUT=<file-path>",
- " Redirects the output to a file. The file created will",
- " be named <file-path> (if <file-path> does not have an",
- " extension, `.STS' is appended automatically). If /OUTPUT",
- " is not specified, the output is displayed at the terminal.",
- #endif
- #if defined(unix) | defined(__MSDOS__)
- " -output <file-path>",
- " Redirects the output to a file. The file created will",
- " be named <file-path> (if <file-path> does not have an",
- " extension, `.sts' is appended automatically). If /OUTPUT",
- " is not specified, the output is displayed at the terminal.",
- #endif
- "",
- #if defined(vms)
- "Example(s): $ CDFSTATS/NORANGE/NOFILL GISS_SOIL",
- " $ CDFSTATS/OUTPUT=TEMPLATE3 CDF$SMPL:TEMPLATE3",
- #endif
- #if defined(unix)
- "Example(s): % cdfstats -norange -nofill giss_soil",
- " % cdfstats -output template3 ../../samples/template3",
- #endif
- #if defined(__MSDOS__)
- "Example(s): > cdfstats gisswetl",
- " > cdfstats -norange -nofill a:\\gisssoil",
- " > cdfstats -output tplate3 ..\\..\\samples\\tplate3",
- #endif
- NULL };
-
- /******************************************************************************
- * ConvertDataType.
- ******************************************************************************/
-
- #define CONVERT(Type1,dataType2,ptr1,ptr2) { \
- switch (dataType2) { \
- case CDF_BYTE: \
- case CDF_INT1: \
- *((Schar *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_UINT1: \
- *((Uchar *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_INT2: \
- *((short *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_UINT2: \
- *((unsigned short *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_INT4: \
- *((long *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_UINT4: \
- *((unsigned long *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_FLOAT: \
- case CDF_REAL4: \
- *((float *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_EPOCH: \
- case CDF_DOUBLE: \
- case CDF_REAL8: \
- *((double *) ptr2) = *((Type1 *) ptr1); \
- break; \
- case CDF_CHAR: \
- case CDF_UCHAR: \
- /* Do nothing for now. */ \
- break; \
- } \
- }
-
- void ConvertDataType (dataType1, numElems1, dataType2, numElems2, ptr1, ptr2)
- long dataType1, numElems1, dataType2, numElems2;
- void *ptr1, *ptr2;
- {
- size_t len;
- int i;
- switch (dataType1) {
- case CDF_BYTE:
- case CDF_INT1:
- CONVERT (Schar, dataType2, ptr1, ptr2);
- break;
- case CDF_UINT1:
- CONVERT (Uchar, dataType2, ptr1, ptr2);
- break;
- case CDF_INT2:
- CONVERT (short, dataType2, ptr1, ptr2);
- break;
- case CDF_UINT2:
- CONVERT (unsigned short, dataType2, ptr1, ptr2);
- break;
- case CDF_INT4:
- CONVERT (long, dataType2, ptr1, ptr2);
- break;
- case CDF_UINT4:
- CONVERT (unsigned long, dataType2, ptr1, ptr2);
- break;
- case CDF_FLOAT:
- case CDF_REAL4:
- CONVERT (float, dataType2, ptr1, ptr2);
- break;
- case CDF_EPOCH:
- case CDF_DOUBLE:
- case CDF_REAL8:
- CONVERT (double, dataType2, ptr1, ptr2);
- break;
- case CDF_CHAR:
- case CDF_UCHAR:
- if (dataType2 == CDF_CHAR || dataType2 == CDF_UCHAR) {
- len = (numElems1 < numElems2 ? numElems1 : numElems2);
- memmove (ptr2, ptr1, len);
- for (i = len; i < numElems2; i++) *((Byte *) ptr2) = ' ';
- }
- break;
- }
- return;
- }
-
- /******************************************************************************
- * CDFstats (MAIN).
- ******************************************************************************/
-
- #if defined(vms)
- main (argc, argv)
- #else
- void main (argc, argv)
- #endif
- int argc;
- char *argv[];
- {
- CDFstatus status;
- char oSpec[MAX_PATH_LEN+1];
- char oDir[MAX_DIR_LEN+1];
- char oName[MAX_NAME_LEN+1];
- long recVary;
- long dimVarys[CDF_MAX_DIMS];
- long dataTypeE; /* data type for attribute entry */
- long numElemsE; /* number of elements for attribute
- entry */
- long maxRec;
- long varMaxRec;
- long numVars;
- long varN; /* variable number */
- long NrecValues; /* number of values per record */
- long numDims;
- long dimSizes[CDF_MAX_DIMS];
- long indices[CDF_MAX_DIMS];
- long counts[CDF_MAX_DIMS];
- long intervals[CDF_MAX_DIMS];
- char varName[CDF_VAR_NAME_LEN+1];
- char CDFpath[CDF_PATHNAME_LEN+1];
- long i;
- long varyCount;
- long count;
- long validminAttrN; /* attribute number */
- long validmaxAttrN; /* attribute number */
- long fillvalAttrN;
- void *temp;
- char delim;
-
- QOP *qop;
- static char *validQuals[] = { "range", "norange", "output",
- "fill", "nofill", NULL };
- static int optRequired[] = { FALSE, FALSE, TRUE,
- FALSE, FALSE, 0 };
-
- /******************************************************************************
- * Get qualifiers/options/parameters.
- ******************************************************************************/
-
- switch (argc == 1) {
- case 1:
- PageInst (instructions);
- Exit;
- default:
- qop = Qop (argc, argv, validQuals, optRequired);
- if (qop == NULL) ExitBAD;
-
- /**************************************************************************
- * Get CDF path parameter.
- **************************************************************************/
-
- if (qop->Nparms < 1) {
- printf ("Missing parameters.\n");
- ExitBAD;
- }
- else
- strcpy (CDFpath, qop->parms[0]);
-
- /**************************************************************************
- * Check for /[NO]RANGE,-[no]range qualifier.
- **************************************************************************/
-
- count = 0;
- if (qop->qualEntered[0]) count++;
- if (qop->qualEntered[1]) count++;
-
- switch (count) {
- case 0:
- #if NSSDC_STANDARD
- rangeCheck = TRUE;
- #else
- rangeCheck = FALSE;
- #endif
- break;
- case 1:
- if (qop->qualEntered[0])
- rangeCheck = TRUE;
- else
- rangeCheck = FALSE;
- break;
- case 2:
- printf ("Conflicting qualifiers.\n");
- ExitBAD;
- }
-
- /**************************************************************************
- * Check for /OUTPUT,-output qualifier.
- **************************************************************************/
-
- if (qop->qualEntered[2]) {
- strcpy (oSpec, qop->qualOpt[2]);
- ParsePath (oSpec, oDir, oName);
- if (strchr(oName,'.') == NULL) strcat (oSpec, ".sts");
- OUTfp = fopen (oSpec, "w");
- if (OUTfp == NULL) {
- printf ("Unable to open output file (%s).", oSpec);
- ExitBAD;
- }
- }
- else
- OUTfp = stdout;
-
- /**************************************************************************
- * Check for /[NO]FILL,-[no]fill qualifier.
- **************************************************************************/
-
- count = 0;
- if (qop->qualEntered[3]) count++;
- if (qop->qualEntered[4]) count++;
-
- switch (count) {
- case 0:
- #if NSSDC_STANDARD
- filterFills = TRUE;
- #else
- filterFills = FALSE;
- #endif
- break;
- case 1:
- if (qop->qualEntered[3])
- filterFills = TRUE;
- else
- filterFills = FALSE;
- break;
- case 2:
- printf ("Conflicting qualifiers.\n");
- ExitBAD;
- }
-
- break;
- }
-
- /******************************************************************************
- * Open CDF.
- ******************************************************************************/
-
- status = CDFlib (OPEN_, CDF_, CDFpath, &id,
- GET_, CDF_NUMDIMS_, &numDims,
- CDF_DIMSIZES_, dimSizes,
- CDF_NUMVARS_, &numVars,
- CDF_MAXREC_, &maxRec,
- NULL_);
- CHECKstatus (status);
-
- if (maxRec == -1) {
- fprintf (OUTfp, "There are no records in the CDF.\n");
- CDFlib (SELECT_, CDF_, id,
- CLOSE_, CDF_,
- NULL_);
- Exit;
- }
-
- if (numVars == 0) {
- fprintf (OUTfp, "There are no variables in the CDF.\n");
- CDFlib (SELECT_, CDF_, id,
- CLOSE_, CDF_,
- NULL_);
- Exit;
- }
-
- for (i = 0; i < numDims; i++) {
- indices[i] = 0;
- intervals[i] = 1;
- }
-
- status = CDFlib (SELECT_, CDF_, id,
- CDF_RECCOUNT_, (long) 1,
- CDF_RECINTERVAL_, (long) 1,
- CDF_DIMINDICES_, indices,
- CDF_DIMINTERVALS_, intervals,
- NULL_);
- CHECKstatus (status);
-
- if (rangeCheck) {
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ATTR_NUMBER_, "VALIDMIN", &validminAttrN,
- ATTR_NUMBER_, "VALIDMAX", &validmaxAttrN,
- NULL_);
- if (status == NO_SUCH_ATTR)
- rangeCheck = FALSE;
- else
- CHECKstatus (status);
- }
-
- if (filterFills) {
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ATTR_NUMBER_, "FILLVAL", &fillvalAttrN,
- NULL_);
- if (status == NO_SUCH_ATTR)
- filterFills = FALSE;
- else
- CHECKstatus (status);
- }
-
- /******************************************************************************
- * Determine statistics for each variable.
- ******************************************************************************/
-
- for (varN = 0; varN < numVars; varN++) {
- status = CDFlib (SELECT_, CDF_, id,
- VAR_, varN,
- GET_, VAR_NAME_, varName,
- VAR_DATATYPE_, &dataTypeV,
- VAR_NUMELEMS_, &numElemsV,
- VAR_RECVARY_, &recVary,
- VAR_DIMVARYS_, dimVarys,
- NULL_);
- CHECKstatus (status);
-
- fprintf (OUTfp, "\n");
- fprintf (OUTfp, "\n");
- delim = PickDelim (varName);
- fprintf (OUTfp, "%3ld. %c%s%c ", varN + 1, delim, varName, delim);
- fprintf (OUTfp, " %s/", TFvarianceToken(recVary));
- for (i = 0; i < numDims; i++)
- fprintf (OUTfp, "%s", TFvarianceToken(dimVarys[i]));
- fprintf (OUTfp, " (%s)", DataTypeToken(dataTypeV));
- fprintf (OUTfp, "\n");
- fprintf (OUTfp, "\n");
-
- if (rangeCheck) {
- rangeCheckVar = TRUE;
-
- status = CDFlib (SELECT_, CDF_, id,
- ATTR_, validminAttrN,
- ENTRY_, varN,
- NULL_);
- if (status == NO_SUCH_ENTRY)
- rangeCheckVar = FALSE;
- else {
- CHECKstatus (status);
- MALLOC (validmin, ElemSize(dataTypeV) * numElemsV);
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ENTRY_DATATYPE_, &dataTypeE,
- ENTRY_NUMELEMS_, &numElemsE,
- NULL_);
- CHECKstatus (status);
- MALLOC (temp, ElemSize(dataTypeE) * numElemsE);
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ENTRY_DATA_, temp,
- NULL_);
- CHECKstatus (status);
- ConvertDataType (dataTypeE, numElemsE, dataTypeV, numElemsV,
- temp, validmin);
- free (temp);
-
- status = CDFlib (SELECT_, CDF_, id,
- ATTR_, validmaxAttrN,
- ENTRY_, varN,
- NULL_);
- if (status == NO_SUCH_ENTRY) {
- rangeCheckVar = FALSE;
- free (validmin);
- }
- else {
- CHECKstatus (status);
- MALLOC (validmax, ElemSize(dataTypeV) * numElemsV);
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ENTRY_DATATYPE_, &dataTypeE,
- ENTRY_NUMELEMS_, &numElemsE,
- NULL_);
- CHECKstatus (status);
- MALLOC (temp, ElemSize(dataTypeE) * numElemsE);
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ENTRY_DATA_, temp,
- NULL_);
- CHECKstatus (status);
- ConvertDataType (dataTypeE, numElemsE, dataTypeV, numElemsV,
- temp, validmax);
- free (temp);
- }
- }
- }
- else
- rangeCheckVar = FALSE;
-
- if (filterFills) {
- filterFillsVar = TRUE;
-
- status = CDFlib (SELECT_, CDF_, id,
- ATTR_, fillvalAttrN,
- ENTRY_, varN,
- NULL_);
- if (status == NO_SUCH_ENTRY)
- filterFillsVar = FALSE;
- else {
- CHECKstatus (status);
- MALLOC (fillval, ElemSize(dataTypeV) * numElemsV);
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ENTRY_DATATYPE_, &dataTypeE,
- ENTRY_NUMELEMS_, &numElemsE,
- NULL_);
- CHECKstatus (status);
- MALLOC (temp, ElemSize(dataTypeE) * numElemsE);
- status = CDFlib (SELECT_, CDF_, id,
- GET_, ENTRY_DATA_, temp,
- NULL_);
- CHECKstatus (status);
- ConvertDataType (dataTypeE, numElemsE, dataTypeV, numElemsV,
- temp, fillval);
- free (temp);
- }
- }
- else
- filterFillsVar = FALSE;
-
- /***************************************************************************
- * Determine how to read records.
- ***************************************************************************/
-
- NrecValues = 1;
-
- for (i = 0; i < numDims; i++) {
- if (dimVarys[i]) {
- NrecValues *= dimSizes[i];
- counts[i] = dimSizes[i];
- }
- else {
- counts[i] = 1;
- }
- }
-
- if (recVary)
- varMaxRec = maxRec;
- else
- varMaxRec = 0;
-
- /***************************************************************************
- * Determine if monotonicity will be checked.
- ***************************************************************************/
-
- if (recVary)
- varyCount = 1;
- else
- varyCount = 0;
-
- for (i = 0; i < numDims; i++) if (dimVarys[i]) varyCount++;
-
- if (varyCount == 1)
- checkMonotonicVar = TRUE;
- else
- checkMonotonicVar = FALSE;
-
- /***************************************************************************
- * Read each record and calculate statistics.
- ***************************************************************************/
-
- status = CDFlib (SELECT_, CDF_, id,
- VAR_, varN,
- CDF_DIMCOUNTS_, counts,
- NULL_);
- CHECKstatus (status);
-
- CALCstat (varMaxRec, NrecValues);
-
- if (rangeCheckVar) {
- free (validmin);
- free (validmax);
- }
-
- if (filterFillsVar) free (fillval);
- }
-
- /******************************************************************************
- * Close CDF and output file (if specified).
- ******************************************************************************/
-
- status = CDFlib (SELECT_, CDF_, id,
- CLOSE_, CDF_,
- NULL_);
- CHECKstatus (status);
-
- if (OUTfp != stdout) fclose (OUTfp);
-
- Exit;
- }
-